package org.example.iot;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioChannelOption;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class Test0x2001 {

    public static void main(String[] args) throws InterruptedException {
        NioEventLoopGroup worker = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.channel(NioSocketChannel.class);
        bootstrap.group(worker);
        bootstrap.option(NioChannelOption.TCP_NODELAY, true);
        bootstrap.handler(new ChannelInitializer<NioSocketChannel>() {
            @Override
            protected void initChannel(NioSocketChannel ch) throws Exception {
                ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
                    //和服务器建立连接之后的回调
                    @Override
                    public void channelActive(ChannelHandlerContext ctx) throws Exception {
                        System.out.println("连接建立");
                        //执行登录
                        byte[] loginBytes = ByteBufUtil.decodeHexDump("028f525c6500990001014457475a434a59323131313038393939322e30322e30303031015b525c6538363531333730363131313638383934363030383435343337303332383338393836303443353130323232303237333238331f3c1f0501000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009f130d0a");
                        ctx.writeAndFlush(Unpooled.buffer().writeBytes(loginBytes));
                        TimeUnit.SECONDS.sleep(5);


                        /**
                         * 025034dc5f002b000202010101014457475a434a59323331323138313032010101014457475a434a5932333132313831303376b50d0a
                         */
                        //上报传感器信息
                        //头部
                        byte[] bytes1 = ByteBufUtil.decodeHexDump("025034dc5f");

                        ByteBuf byteBuf= ByteBufAllocator.DEFAULT.buffer();
                        byteBuf.writeBytes(bytes1);
                        //数据长度 = 指令码 + 传感器数量 + 传感器信息
                        byteBuf.writeShort(2+1+(20*16));
                        //写入指令码
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("0002"));
                        //写入传感器数量
                        byteBuf.writeByte(16);
                        //写入20字节445747
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("01010a01"));
                        byteBuf.writeBytes("DWGZCJY231100001".getBytes(StandardCharsets.UTF_8));
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("02010a01"));
                        byteBuf.writeBytes("DWGZCJY231100002".getBytes(StandardCharsets.UTF_8));
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("03010a01"));
                        byteBuf.writeBytes("DWGZCJY231100003".getBytes(StandardCharsets.UTF_8));
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("04010a01"));
                        byteBuf.writeBytes("DWGZCJY231100004".getBytes(StandardCharsets.UTF_8));
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("05010a01"));
                        byteBuf.writeBytes("DWGZCJY231100005".getBytes(StandardCharsets.UTF_8));
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("06010a01"));
                        byteBuf.writeBytes("DWGZCJY231100006".getBytes(StandardCharsets.UTF_8));
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("07010a01"));
                        byteBuf.writeBytes("DWGZCJY231100007".getBytes(StandardCharsets.UTF_8));
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("08010a01"));
                        byteBuf.writeBytes("DWGZCJY231100008".getBytes(StandardCharsets.UTF_8));
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("09010a01"));
                        byteBuf.writeBytes("DWGZCJY231100009".getBytes(StandardCharsets.UTF_8));
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("0a010a01"));
                        byteBuf.writeBytes("DWGZCJY231100010".getBytes(StandardCharsets.UTF_8));
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("0b010a01"));
                        byteBuf.writeBytes("DWGZCJY231100011".getBytes(StandardCharsets.UTF_8));
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("0c010a01"));
                        byteBuf.writeBytes("DWGZCJY231100012".getBytes(StandardCharsets.UTF_8));
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("0d010a01"));
                        byteBuf.writeBytes("DWGZCJY231100013".getBytes(StandardCharsets.UTF_8));
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("0e010a01"));
                        byteBuf.writeBytes("DWGZCJY231100014".getBytes(StandardCharsets.UTF_8));
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("0f010a01"));
                        byteBuf.writeBytes("DWGZCJY231100015".getBytes(StandardCharsets.UTF_8));
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("10010a01"));
                        byteBuf.writeBytes("DWGZCJY231100017".getBytes(StandardCharsets.UTF_8));
                        //写入CRE
                        byte[] crcBytes = crc16CCITTFalse(ByteBufUtil.getBytes(byteBuf));
                        byteBuf.writeBytes(crcBytes);
                        //写入尾部
                        byteBuf.writeBytes(ByteBufUtil.decodeHexDump("0d0a"));
                        ctx.writeAndFlush(byteBuf);


                        /**
                         * 上传数据包
                         */
                        int num=0;
                        while (true){
                            ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer();
                            long time = (new Date().getTime() );
                            buffer.writeBytes(ByteBufUtil.decodeHexDump("02f9dc8c6608312001ef2e0000"));
                            buffer.writeLongLE(time);
                            buffer.writeBytes(ByteBufUtil.decodeHexDump("1020800102000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002006bf3803ff6e9803f00e6803f8ee8803fdbea803fd1ee803f99ea803f19df803f0be8803f6fee803fc7f2803f76f5803fbdf6803fcbed803f43ec803f5ce5803f8ee8803fb6ef803f01ec803f47e7803fc0eb803fb4e9803ff3f4803f50f4803f73e9803f79ea803f3ff1803fa6f2803f54ef803f3be5803fbee5803fe1eb803f030052e9803fa0da803f81e0803f47e7803fc6ec803f0be8803f7bdf803f7bdf803fcae7803f22ec803fd3e3803f5ce5803f8ee8803f9feb803f94e9803f70dd803f5adf803f7eeb803fa3e6803f05e7803f13de803f90dd803f0be8803f69ed803f3adf803f9cdf803f81e0803fb4e9803f9de5803f49dc803fc2e0803f58ea803f04002b687d3f544d7d3fe65b7d3f066d7d3f2b687d3f9f5a7d3f1c5a7d3fbf6b7d3ff8757d3f8b627d3f3b547d3f5e717d3ff2747d3fde657d3fd5587d3f5d5a7d3f58707d3f946f7d3fdd4e7d3ff15d7d3f0b6e7d3f58707d3fcc627d3fff547d3f635b7d3fc8787d3f366a7d3f16597d3f10587d3f25677d3f116f7d3f58597d3f0500f4db783fb5d0783fc0d2783f09b2783f37ba783f68ce783fe3d8783f5fc1783fd9b4783f0cbe783f70c4783f21cd783ff0cf783fa0c1783fd1d5783f1daa783fc8b1783f45c8783f54d6783febce783f01bc783f03b1783f57cb783f10e1783f68ce783fc8b1783ff0b8783fd9b4783f43d3783ff3c4783ff0b8783f9bc0783f060024507d3fce407d3f8d407d3f2f527d3faf467d3fe34f7d3f854a7d3fe5447d3fc0497d3f194e7d3f15427d3fbe547d3fdf437d3fee517d3f194e7d3fd6367d3fc83f7d3ffc487d3f873f7d3f5a4e7d3f46567d3ff0467d3f5d5a7d3f544d7d3f4b407d3f71527d3f494b7d3f194e7d3fa14f7d3fe2387d3f024a7d3fee517d3f070072107f3fc4fc7e3fed1a7f3f51217f3f37117f3f75057f3fe40d7f3fc81f7f3f32277f3f6d0f7f3ff2047f3fc62a7f3fa12f7f3f0f217f3f0e0a7f3fc2077f3ff81c7f3f842a7f3fb0047f3fec037f3f7e127f3f6d267f3f37287f3f78117f3ffd067f3f17177f3f041f7f3f041f7f3fb6057f3fa80e7f3f26257f3fb4277f3f08000982813f2d77813ffe7f813ff27d813ff87e813f347e813f9c7f813fe380813f7b7f813fa180813f6a7c813f2687813fd383813f4b82813f4581813f237b813f347e813fb383813f237b813f707d813f5378813fa67b813ffe7f813fd77e813fbf74813fa07a813fcc7c813f0b88813fe380813ff177813f7478813f1f80813f090072107f3f910a7f3fac317f3f743e7f3f9a177f3f2b0f7f3f871f7f3f29317f3f7e297f3f250e7f3f48147f3ffc3f7f3fd8447f3fbd1d7f3f03087f3f06147f3faa3c7f3f10387f3fbc067f3f910a7f3f9b2e7f3ff9337f3f451f7f3fde0c7f3f23197f3fc3357f3fda397f3f48147f3f80077f3fc21e7f3f9e3a7f3fc62a7f3f0a00b76c7f3ff5607f3fb2827f3f24977f3f40857f3fd0657f3fce707f3faa8c7f3f49927f3fe5747f3fa6697f3f19957f3f28a37f3fff847f3f06647f3fd0657f3f66977f3f5a957f3fa6697f3f296a7f3f9b7e7f3f0e937f3f93887f3f42637f3f5f687f3f6e8d7f3f1ca17f3f8d877f3ffe6d7f3f437a7f3fb89a7f3f44917f3f0b00a15f7c3f2c3f7c3f1e487c3f93687c3f03717c3fe35f7c3ff94c7c3faf567c3f4a727c3f396f7c3fe5547c3f814e7c3fd75d7c3fdb697c3f38587c3f5c3c7c3fdc477c3f636b7c3fc7717c3f085b7c3f73407c3fa6497c3f0e737c3f7a6f7c3f764c7c3fc0427c3f044f7c3fb8637c3f1e5f7c3f9b477c3fff4d7c3f47667c3f0c0039f0803f07ed803f6ce2803f34de803f51e3803f2dee803f36e4803f68d6803f48d6803fdfe5803f75ef803f47e7803fd8de803fdddf803f4de8803fcee2803f48d6803fb5d8803fd9e4803f90ee803f98e4803f53d8803f0be8803fd3f4803f65f2803ffae4803f32d8803f36e4803f3ff1803f01ec803f5ce5803fb3e3803f0d00639c803f6a8c803f8e98803fb2a4803ff29e803f0597803f1f90803f229c803f6f9e803f1199803f0491803f959f803f61a7803f18a0803f6897803f5193803f909e803f29a3803ffa94803f7d95803f439c803f699d803f179a803f0f93803f1594803fc09b803fba9a803fc891803f3a8f803f6d98803f5aa0803f8e98803f0e0057d97f3f35d37f3fa4db7f3f51d87f3f0ad77f3f48cb7f3f5ace7f3ff9d37f3f4ecc7f3fe5db7f3f7fe07f3fe6f27f3fb3e97f3f43e17f3f27dc7f3f05d67f3fc6e17f3f08e27f3fd7cd7f3fe0da7f3f93d87f3f16d97f3ff7de7f3f5dda7f3fd7cd7f3f02e17f3f32de7f3fb5de7f3f3ad47f3fe8d07f3f32de7f3f32de7f3f0f006068803f7e5c803f375b803f8563803fb36b803fb766803f635d803f065e803fed64803f1967803f7a61803f1761803f5f62803f5566803f8769803f5360803fc162803f6669803f1967803f7065803f015d803f0a59803f5b67803f1772803ff866803f575b803f3c5c803f7566803f5c6d803fe162803fc958803f895e803f10001e41813ff82e813f6a2c813f583a813f8041813fa336813ff127813fc230813f6b43813fd13e813fd333813f3139813f903e813f223c813f552e813f642b813f0d3e813fe447813f3d3b813fdf35813fe13b813f0342813f843c813fbd2f813f3f30813f8041813f3940813f5634813ff82e813fba3a813f2943813fd73f813faebe0d0a"));

                            ctx.writeAndFlush(buffer);
                            num++;
                            System.out.println("第"+num+"次循环");
                            Thread.sleep(5000);

                        }



                    }
                });
            }
        });
        ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 9876).sync();
        Channel channel = channelFuture.channel();

    }

    public static byte[] crc16CCITTFalse(byte[] bytes) {
        int crc = 0xffff; // initial value
        int polynomial = 0x1021; // poly value
        for (int index = 0; index < bytes.length; index++) {
            byte b = bytes[index];
            for (int i = 0; i < 8; i++) {
                boolean bit = ((b >> (7 - i) & 1) == 1);
                boolean c15 = ((crc >> 15 & 1) == 1);
                crc <<= 1;
                if (c15 ^ bit){
                    crc ^= polynomial;
                }
            }
        }
        crc &= 0xffff;
        return new byte[] { (byte) ((0xff00 & crc) >> 8),(byte) (0xff & crc)  };
    }
}
